package com.yelisheng.simulate.core;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;

/**
 * 模拟CPU和内存使用情况的类
 */
@Component
public class CpuMemory {

    // CPU使用率，默认值为0.4
    @Value("${cpuUsage:0.4}")
    private Double cpuUsage;

    // 内存使用率，默认值为0.7
    @Value("${memoryUsage:0.7}")
    private Double memoryUsage;

    /**
     * 启动模拟进程的方法
     */
    public void start() {
        try {
            // 显示参数
            System.out.println("当前配置:");
            System.out.println("CPU使用率: " + cpuUsage);
            System.out.println("内存使用率: " + memoryUsage);

            // CPU模拟
            int numProcessors = Runtime.getRuntime().availableProcessors();
            System.out.println("服务器内核数量: " + numProcessors);

            // 计算需要启动的线程数
            int threadCount = (int) (numProcessors * cpuUsage);
            threadCount = Math.min(threadCount, numProcessors); // 确保不超过核心数
            threadCount = Math.max(threadCount, 0); // 确保不小于0

            System.out.println("启动线程数: " + threadCount);
            for (int p = 0; p < threadCount; p++) {
                new Thread(new CpuLoop()).start();
            }

            // 内存模拟
            long totalMemory = Runtime.getRuntime().totalMemory();
            long memorySize = (long) (totalMemory * memoryUsage / (1024 * 1024)); // 转换为MB
            System.out.println("内存占用大小(MB): " + memorySize);

            if (memorySize > 0) {
                memory(memorySize);
            } else {
                System.out.println("内存使用率设置为0，不进行内存模拟。");
            }
        } catch (NumberFormatException e) {
            System.out.println("参数格式错误，请检查输入参数。");
            System.out.println("使用方式: java CpuMemory [cpuUsage] [memoryUsage]");
            System.out.println("例如: java CpuMemory 0.4 0.7");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * CPU占用线程类
     */
    static class CpuLoop implements Runnable {
        @Override
        public void run() {
            int i = 0;
            while (true) {
                i++;
            }
        }
    }

    /**
     * 内存占用模拟方法
     *
     * @param memorySize 需要模拟占用的内存大小（单位：MB）
     * @throws InterruptedException 如果线程被中断
     */
    static void memory(long memorySize) throws InterruptedException {
        // 由于ArrayList占用额外空间，系数调整为1.3
        memorySize = (long) (memorySize / 1.3);

        // 每个Object对象约16byte，65536个Object约为1MB
        int objCountPerMB = 65536;
        int arrCapacity = (int) (objCountPerMB * memorySize);

        ArrayList<Object> al = new ArrayList<>(arrCapacity);

        // 分配内存
        for (int i = 0; i < memorySize; ++i) {
            for (int j = 0; j < objCountPerMB; ++j) {
                Object obj = new Object();
                al.add(obj);
                obj = null;
            }
        }

        // 防止程序立即退出
        try {
            System.out.println("按任意键退出...");
            System.in.read();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
